/**
 * Copyright 2009 University of Washington This code is released under the GPL version 3 - with a copy of the license
 * included
 * 
 * @author Maya Hao Li
 */
package seedpod.model.rdb;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;

import seedpod.model.InstanceRelationship;

public enum RdbValueType {
	VARCHAR("VARCHAR", String.class) {
		@Override
		public String valueToString( Object data ) {
			return (data != null) ? data.toString() : null;
		}
	},
	INTEGER("INTEGER", Integer.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data instanceof Integer ) return ((Integer)data).toString();
			try {
				return Integer.valueOf( data.toString() ).toString();
			} catch (Exception e) {
				return null;
			}
		}
	},
	NUMERIC("NUMERIC", Float.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data instanceof Float ) return ((Float)data).toString();
			try {
				return Float.valueOf( data.toString() ).toString();
			} catch (Exception e) {
				return null;
			}
		}
	},
	TEXT("TEXT", String.class) {
		@Override
		public String valueToString( Object data ) {
			return VARCHAR.valueToString( data );
		}
	},
	CHARACTER("CHARACTER", String.class) {
		@Override
		public String valueToString( Object data ) {
			return VARCHAR.valueToString( data );
		}
	},
	BOOLEAN("BOOLEAN", Boolean.class) {
		@Override
		public String valueToString( Object data ) {
			try {
				return ((Boolean)data).toString();
			} catch (Exception e) {
				return null;
			}
		}
	},
	FOREIGN_KEY("SERIAL", Long.class) {
		@Override
		public String valueToString( Object data ) {
			return SERIAL.valueToString( data );
		}
	},
	DATE("DATE", Date.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data instanceof Date ) return ((Date)data).toString();
			return null;
		}
	},
	TIME("TIME", Time.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data instanceof Time ) return ((Time)data).toString();
			return null;
		}
	},
	TIMESTAMP("TIMESTAMP", Timestamp.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data instanceof Timestamp ) return ((Date)data).toString();
			return null;
		}
	},
	SERIAL("SERIAL", Long.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data == null ) return null;
			try {
				if ( data instanceof Long )
					return data.toString();
				else if ( data instanceof Integer )
					return data.toString();
				else if ( data instanceof InstanceRelationship ) return ((InstanceRelationship)data).toString();
			} catch (ClassCastException e) {
				e.printStackTrace();
				return "(E)Data cast exception to serial type";
			}

			return null;
		}
	},
	RELATION("RELATION", Relation.class) {
		@Override
		public String valueToString( Object data ) {
			if ( data instanceof InstanceRelationship ) {
				InstanceRelationship rel = (InstanceRelationship)data;
				if ( rel.isOneToOne() ) {
					Integer target = rel.getTargetOid();
					return target == null ? "" : target.toString();
				}
			}
			return null;
		}
	};

	private String _sqlname;
	private Class<?> _javaType;

	private RdbValueType(String dbType, Class<?> javaType) {
		_sqlname = dbType;
		_javaType = javaType;
	}

	public boolean equals( RdbValueType o ) {
		return name().equalsIgnoreCase( o.name() );
	}

	public Class<?> getJavaType() {
		return _javaType;
	}

	@Override
	public String toString() {
		return _sqlname;
	}

	public String valueToString( Object data ) throws java.lang.ClassCastException {
		return data.toString();
	}
}